package com.zhe.zheblogmaster.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.zhe.zheblogmaster.config.BlogConstants;
import com.zhe.zheblogmaster.entity.Blog;
import com.zhe.zheblogmaster.entity.BlogCategory;
import com.zhe.zheblogmaster.entity.vo.BlogDetailVO;
import com.zhe.zheblogmaster.entity.vo.BlogVO;
import com.zhe.zheblogmaster.entity.vo.SimpleBlogVO;
import com.zhe.zheblogmaster.mapper.BlogCategoryMapper;
import com.zhe.zheblogmaster.mapper.BlogCommentMapper;
import com.zhe.zheblogmaster.mapper.BlogMapper;
import com.zhe.zheblogmaster.service.BlogService;
import com.zhe.zheblogmaster.util.MarkdownUtil;
import com.zhe.zheblogmaster.util.PatternUtil;
import com.zhe.zheblogmaster.util.ZheBlogUtils;
import lombok.extern.java.Log;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author WHAOU
 * @date 2021/8/22
 * @email whaou@qq.com
 */
@Service
public class BlogServiceImpl implements BlogService {
    @Autowired
    private BlogMapper blogMapper;
    @Autowired
    private BlogCategoryMapper categoryMapper;
    @Autowired
    private BlogCommentMapper commentMapper;

    @Override
    public String updateBlog(Blog blog) {
        Blog blogForUpdate = blogMapper.selectById(blog.getBlogId());
        if (blogForUpdate == null) {
            return "id为" + blog.getBlogId() + "的博客不存在";
        }
        blogForUpdate.setBlogTitle(blog.getBlogTitle());
        blogForUpdate.setBlogContent(blog.getBlogContent());
        blogForUpdate.setBlogStatus(blog.getBlogStatus());
        blogForUpdate.setEnableComment(blog.getEnableComment());
        BlogCategory blogCategory = categoryMapper.selectById(blog.getBlogCategoryId());
        if (blogCategory == null) {
            blogForUpdate.setBlogCategoryId(0);
            blogForUpdate.setBlogCategoryName("默认分类");
        } else {
            //设置博客分类名称
            blogForUpdate.setBlogCategoryName(blogCategory.getCategoryName());
            blogForUpdate.setBlogCategoryId(blogCategory.getCategoryId());
            //分类的排序值加1
            blogCategory.setCategoryRank(blogCategory.getCategoryRank() + 1);
        }
        blogForUpdate.setUpdateTime(ZheBlogUtils.getNow());
        if (blogMapper.updateBlogByIdSelective(blogForUpdate) > 0) {
            categoryMapper.updateByIdSelective(blogCategory);
            return BlogConstants.FEEDBACK_SUCCESS;
        } else {
            return "修改失败";
        }
    }

    @Override
    public int removeBlogsByIds(Long[] ids) {
        return blogMapper.deleteBlogBatchById(ids);
    }

    @Override
    public Blog getBlogById(Long blogId) {
        return blogMapper.selectById(blogId);
    }

    @Override
    @Transactional
    public Boolean saveBlog(Blog blog) {
        BlogCategory category = categoryMapper.selectById(blog.getBlogCategoryId());
        if (category == null) {
            blog.setBlogCategoryId(0);
            blog.setBlogCategoryName("默认分类");
        } else {
            blog.setBlogCategoryName(category.getCategoryName());
            // 博客分类排序值加1
            category.setCategoryRank(category.getCategoryRank() + 1);
        }
        int count = blogMapper.insertSelective(blog);
        if (count > 0) {
            categoryMapper.updateByIdSelective(category);
            return true;
        } else {
            return false;
        }
    }

    @Override
    public Integer getTotalBlogs() {
        return blogMapper.selectCount();
    }

    @Override
    public BlogDetailVO getBlogDetailVOById(Long blogId) {
        Blog blog = blogMapper.selectById(blogId);
        return convertToBlogDetailVO(blog);
    }

    @Override
    public BlogDetailVO getAboutBlog() {
        String content = blogMapper.selectAboutBlog();
        if (content == null) {
            return null;
        }
        BlogDetailVO vo = new BlogDetailVO();
        vo.setBlogContent(MarkdownUtil.mdToHtml(content));
        return vo;
    }

    @Override
    public PageInfo<SimpleBlogVO> getSimpleBlogVOByCategoryName(String categoryName, Integer pageNum) {
        if (!PatternUtil.validKeyword(categoryName)) {
            return null;
        }
        Map<String, Object> condition = new HashMap<>(2);
        // 查询发布状态的博客
        condition.put(BlogConstants.BLOG_STATUS, BlogConstants.BLOG_STATUS_PUBLISHED);
        BlogCategory category = categoryMapper.selectByName(categoryName);
        if (category == null) {
            condition.put("blogCategoryId", 0);
        } else {
            condition.put("blogCategoryId", category.getCategoryId());
        }
        PageInfo<Blog> blogs = this.getBlogsByMap(pageNum, condition);
        PageInfo<SimpleBlogVO> simpleBlogVOPageInfo = new PageInfo<>();
        BeanUtils.copyProperties(blogs, simpleBlogVOPageInfo);
        return simpleBlogVOPageInfo;
    }


    @Override
    public PageInfo<SimpleBlogVO> getBlogVOListByKeyword(String keyword, Integer pageNum) {
        Map<String, Object> condition = new HashMap<>(2);
        condition.put(BlogConstants.KEYWORD, keyword);
        condition.put(BlogConstants.BLOG_STATUS, BlogConstants.BLOG_STATUS_PUBLISHED);
        PageInfo<Blog> blogs = this.getBlogsByMap(pageNum, condition);

        PageInfo<SimpleBlogVO> simpleBlogVOPageInfo = new PageInfo<>();
        BeanUtils.copyProperties(blogs, simpleBlogVOPageInfo);
        return simpleBlogVOPageInfo;
    }


    @Override
    public PageInfo<BlogVO> getBlogVOList(int pageNum) {
        // 封装查询条件 博客状态为1，即发布状态
        Map<String, Object> condition = new HashMap<>(1);
        condition.put(BlogConstants.BLOG_STATUS, BlogConstants.BLOG_STATUS_PUBLISHED);
        PageInfo<Blog> blogs = this.getBlogsByMap(pageNum, condition);
        // 封装为界面显示数据
        PageInfo<BlogVO> blogVOPageInfo = new PageInfo<>();
        BeanUtils.copyProperties(blogs, blogVOPageInfo);
        blogVOPageInfo.setList(convertToBlogVO(blogs.getList()));
        return blogVOPageInfo;
    }

    @Override
    public List<SimpleBlogVO> getHotBlogs(int limit) {
        List<Blog> hotBlogList = blogMapper.selectHotBlogList(limit);
        return convertToSimpleBlogVO(hotBlogList);
    }

    @Override
    public List<SimpleBlogVO> getLatestBlogRecords(int limit) {
        List<Blog> latestBlogList = blogMapper.selectLatestBlogList(limit);
        return convertToSimpleBlogVO(latestBlogList);
    }

    @Override
    public PageInfo<Blog> getBlogsByMap(int pageNum, Map<String, Object> condition) {
        PageHelper.startPage(pageNum, BlogConstants.DEFAULT_PAGE_SIZE);
        List<Blog> blogList = blogMapper.selectBlogSelective(condition);
        return new PageInfo<>(blogList);
    }

    private BlogDetailVO convertToBlogDetailVO(Blog blog) {
        if (blog == null) {
            return null;
        }
        // 增加浏览量
        blogMapper.updateBlogViewsById(blog.getBlogId(), blog.getBlogViews() + 1);
        BlogDetailVO blogDetailVO = new BlogDetailVO();
        BeanUtils.copyProperties(blog, blogDetailVO);
        // 将博客内容由markdown转为html页面
        blogDetailVO.setBlogContent(MarkdownUtil.mdToHtml(blog.getBlogContent()));
        BlogCategory blogCategory = categoryMapper.selectById(blog.getBlogCategoryId());
        if (blogCategory == null) {
            // 设置为默认分类
            blogDetailVO.setBlogCategoryId(0);
            blogDetailVO.setBlogCategoryName("默认分类");
            blogDetailVO.setBlogCategoryIcon("/customize/category/00.png");
        } else {
            blogDetailVO.setBlogCategoryIcon(blogCategory.getCategoryIcon());
        }
        // 设置评论数
        Map<String, Object> params = new HashMap<>(2);
        params.put("blogId", blog.getBlogId());
        params.put("commentStatus", 1);
        Integer count = commentMapper.selectTotalOfComment(params);
        blogDetailVO.setCommentCount(count);
        return blogDetailVO;
    }

    private List<SimpleBlogVO> convertToSimpleBlogVO(List<Blog> blogList) {
        ArrayList<SimpleBlogVO> simpleBlogVOList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(blogList)) {
            for (Blog blog : blogList) {
                SimpleBlogVO simpleBlogVO = new SimpleBlogVO();
                BeanUtils.copyProperties(blog, simpleBlogVO);
                simpleBlogVOList.add(simpleBlogVO);
            }
        }
        return simpleBlogVOList;
    }

    /**
     * 将blog对象封装为blogVO对象
     *
     * @param blogList blog集合
     * @return 封装后的blogVO集合
     */
    private List<BlogVO> convertToBlogVO(List<Blog> blogList) {
        List<BlogVO> blogVOList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(blogList)) {
            for (Blog blog : blogList) {
                BlogVO blogVO = new BlogVO();
                BeanUtils.copyProperties(blog, blogVO);
                blogVOList.add(blogVO);
            }
        }
        return blogVOList;
    }
}
